/*******************************************************************************
 * Copyright (c) Jonathan Buck - jonbuck16@gmail.com
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    jonbuck16@gmail.com - initial API and implementation
 *******************************************************************************/
package net.jonbuck.tassoo.ui.preference;

import net.jonbuck.tassoo.eventmanager.EventManager;
import net.jonbuck.tassoo.eventmanager.EventManagerImpl;
import net.jonbuck.tassoo.eventmanager.events.AttachmentTypesUpdatedEvent;
import net.jonbuck.tassoo.model.AttachmentType;
import net.jonbuck.tassoo.model.AttachmentTypes;
import net.jonbuck.tassoo.model.TassooFactory;
import net.jonbuck.tassoo.model.TassooPackage;
import net.jonbuck.tassoo.model.provider.TassooItemProviderAdapterFactory;
import net.jonbuck.tassoo.persistence.dao.TassooDao;
import net.jonbuck.tassoo.persistence.dao.TassooDaoImpl;
import net.jonbuck.tassoo.ui.dialog.AttachmentTypeDialog;
import net.jonbuck.tassoo.ui.nl.Messages;

import org.eclipse.emf.ecore.change.util.ChangeRecorder;
import org.eclipse.emf.edit.command.AddCommand;
import org.eclipse.emf.edit.command.RemoveCommand;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;

/**
 * 
 * 
 * @since 1.0.0
 */
public class AttachmentTypesPreferencePage extends PreferencePage implements IWorkbenchPreferencePage, ISelectionChangedListener {

	private TassooItemProviderAdapterFactory adapterFactory;

	private TassooDao tassooDao = TassooDaoImpl.getInstance();

	private AdapterFactoryEditingDomain editingDomain;

	private AttachmentTypes attachmentTypes;

	private Table table;

	private AttachmentType selectedAttachmentType;

	private ChangeRecorder recorder;

	private Button addButton;

	private Button editButton;

	private Button deleteButton;

	private EventManager eventManager = EventManagerImpl.getInstance();

	/**
	 * 
	 */
	public AttachmentTypesPreferencePage() {
		super();
	}

	/**
	 * <p>
	 * <b>Initialises the preference page by setting the description and image
	 * and then retrieving the attachments types from the current task store if
	 * there is one open.</b>
	 * </p>
	 */
	public void init(IWorkbench workbench) {
		this.setDescription(Messages.attachmenttypespreferencepage_description);
		this.noDefaultAndApplyButton();
		adapterFactory = new TassooItemProviderAdapterFactory();
		editingDomain = tassooDao.getEditingDomain();
		if (tassooDao.isLoaded()) {
			this.attachmentTypes = tassooDao.getAttachmentTypes();
		}
	}

	/**
	 * <p>
	 * <b>Creates the user interface for the preference page.</b><br/>
	 * The preference page consists of a table which displays the current list
	 * of attachment types and allows the user to specify more types.
	 * </p>
	 */
	protected Control createContents(Composite parent) {
		Composite contents = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout(2, false);
		layout.marginHeight = layout.marginWidth = 0;
		contents.setLayout(layout);

		TableLayout tableLayout = new TableLayout();

		table = new Table(contents, SWT.BORDER | SWT.FULL_SELECTION);
		table.setLayout(tableLayout);
		table.setHeaderVisible(true);
		table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		table.addListener(SWT.MeasureItem, new Listener() {
			public void handleEvent(Event event) {
				event.height = 18;
			}
		});

		TableColumn nameColumn = new TableColumn(table, SWT.NONE);
		nameColumn.setText(Messages.attachmenttypespreferencepage_column_title_name);
		tableLayout.addColumnData(new ColumnWeightData(35));
		
		TableColumn typeColumn = new TableColumn(table, SWT.NONE);
		typeColumn.setText(Messages.attachmenttypespreferencepage_column_title_type);
		tableLayout.addColumnData(new ColumnWeightData(20));

		TableColumn commandColumn = new TableColumn(table, SWT.NONE);
		commandColumn.setText(Messages.attachmenttypespreferencepage_column_title_command);
		tableLayout.addColumnData(new ColumnWeightData(25));

		TableColumn extensionColumn = new TableColumn(table, SWT.NONE);
		extensionColumn.setText(Messages.attachmenttypespreferencepage_column_title_extension);
		tableLayout.addColumnData(new ColumnWeightData(20));

		final TableViewer attachmentsViewer = new TableViewer(table);
		attachmentsViewer.setComparator(new ViewerComparator());
		attachmentsViewer.addSelectionChangedListener(this);
		attachmentsViewer.setContentProvider(new AdapterFactoryContentProvider(adapterFactory));
		attachmentsViewer.setLabelProvider(new AdapterFactoryLabelProvider(adapterFactory));
		if (tassooDao.isLoaded()) {
			recorder = new ChangeRecorder(attachmentTypes);
			attachmentsViewer.setInput(attachmentTypes);
		}

		Composite buttons = new Composite(contents, SWT.NONE);
		GridData buttonsGridData = new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1);
		buttonsGridData.widthHint = 80;
		buttons.setLayoutData(buttonsGridData);
		GridLayout buttonsLayout = new GridLayout(1, false);
		buttonsLayout.marginHeight = buttonsLayout.marginWidth = 0;
		buttons.setLayout(buttonsLayout);

		addButton = new Button(buttons, SWT.NONE);
		addButton.setText(Messages.preferencepage_button_title_add);
		addButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
		addButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				AttachmentTypeDialog attachmentTypeDialog = new AttachmentTypeDialog(Display.getCurrent().getActiveShell(),
						TassooFactory.eINSTANCE.createAttachmentType(), attachmentTypes.getAttachmentType(),
						Messages.attachmenttypedialog_addtype_title, Messages.attachmenttypedialog_addtype_message);
				if (attachmentTypeDialog.open() == IDialogConstants.OK_ID) {
					AttachmentType newAttachmentType = attachmentTypeDialog.getAttachmentType();
					editingDomain.getCommandStack().flush();
					editingDomain.getCommandStack().execute(
							AddCommand.create(editingDomain, attachmentTypes,
									TassooPackage.Literals.ATTACHMENT_TYPES__ATTACHMENT_TYPE, newAttachmentType));
					attachmentsViewer.refresh();
					attachmentsViewer.setSelection(new StructuredSelection(newAttachmentType));
				}
			}
		});
		addButton.setEnabled(tassooDao.isLoaded());

		editButton = new Button(buttons, SWT.NONE);
		editButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
		editButton.setText(Messages.preferencepage_button_title_edit);
		editButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				ChangeRecorder editRecorder = new ChangeRecorder(selectedAttachmentType);
				AttachmentTypeDialog attachmentTypeDialog = new AttachmentTypeDialog(Display.getCurrent().getActiveShell(),
						selectedAttachmentType, attachmentTypes.getAttachmentType(), Messages.attachmenttypedialog_edittype_title,
						Messages.attachmenttypedialog_edittype_message);
				if (attachmentTypeDialog.open() == IDialogConstants.OK_ID) {
					editRecorder.endRecording();
				}
			}
		});
		editButton.setEnabled(tassooDao.isLoaded());

		deleteButton = new Button(buttons, SWT.NONE);
		deleteButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
		deleteButton.setText(Messages.preferencepage_button_title_delete);
		deleteButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				if (MessageDialog.openQuestion(
						Display.getCurrent().getActiveShell(),
						Messages.bind(Messages.delete_question, Messages.referencetype_attachmenttype),
						Messages.bind(Messages.delete_message, Messages.referencetype_attachmenttype,
								selectedAttachmentType.getName()))) {
					editingDomain.getCommandStack().flush();
					editingDomain.getCommandStack().execute(
							RemoveCommand.create(editingDomain, attachmentTypes,
									TassooPackage.Literals.ATTACHMENT_TYPES__ATTACHMENT_TYPE, selectedAttachmentType));
				}
			}
		});
		deleteButton.setEnabled(tassooDao.isLoaded());

		if (tassooDao.isLoaded()) {
			AttachmentType attachmentType = attachmentTypes.getAttachmentType().get(0);
			attachmentsViewer.setSelection(new StructuredSelection(attachmentType));
		}

		return contents;
	}

	/**
	 * <p>
	 * <b>Update the list of preferences.</b>
	 * </p>
	 */
	public boolean performOk() {
		if (tassooDao.isLoaded()) {
			recorder.endRecording();
			eventManager.fireEvent(new AttachmentTypesUpdatedEvent());
		}
		return true;
	}

	/**
	 * 
	 */
	public boolean performCancel() {
		if (tassooDao.isLoaded()) {
			recorder.endRecording().applyAndReverse();
		}
		return true;
	}

	/**
	 * 
	 */
	public void selectionChanged(SelectionChangedEvent event) {
		IStructuredSelection selection = (IStructuredSelection) event.getSelection();
		selectedAttachmentType = (AttachmentType) selection.getFirstElement();
	}

}
